Skip to content

📋 问题总结与解答

1. EventListener 重复 ✅ 已修复

  • ❌ 删除:app/.../ActivityEventListener.java

  • ✅ 保留:infrastructure/.../event/listener/ActivityEventListener.java

  • 原因:EventListener 使用了 Spring 技术(@TransactionalEventListener、@Async),应该放在 Infrastructure 层

2. shared 文件夹的作用 ✅ 设计正确

domain/shared 是 DDD 的通用语言层,存放跨聚合根复用的基础组件:

  • shared/event/DomainEvent.java - 事件基类(定义"事件"这个业务概念)

  • shared/event/IDomainEventPublisher.java - 事件发布器接口(Output Port)

  • shared/valobj/ - 通用值对象(BaseId、Money)

类比:shared 就像"工具箱",存放多个聚合根都需要的基础组件。

3. Adapter 重复 ✅ 已修复

  • ❌ 删除:infrastructure/adapter/ActivityNotificationAdapter.java

  • ✅ 保留:infrastructure/adapter/notification/ActivityNotificationAdapter.java

4. 事件监听的 Adapter 设计 ✅ 架构清晰

这是标准的 DDD + 六边形架构,包含 3 个 Adapter:

Adapter类型作用
DomainEventPublisherAdapterDriven Adapter实现 IDomainEventPublisher
将领域事件发布到 Spring Event(或 MQ)
ActivityEventListenerEvent Listener监听 Spring Event
调用 IActivityNotificationPort
ActivityNotificationAdapterDriven Adapter实现 IActivityNotificationPort
整合短信/推送/站内信等通知渠道

🔄 完整调用链

用户操作

ActivityController

ActivityApplicationService
  ├─ aggregate.publishActivity()
  │  └─ addDomainEvent(new ActivityCreatedEvent(...))  [1. 产生事件]

  ├─ domainEventPublisher.publishAll(events)  [2. 调用 Output Port]
  │  ↓
  │  DomainEventPublisherAdapter
  │  └─ applicationEventPublisher.publishEvent(event)  [3. 发布到 Spring Event]

  └─ (事务提交)

     ActivityEventListener
     └─ notificationPort.notifyActivityCreated(event)  [4. 调用 Output Port]

        ActivityNotificationAdapter
        ├─ smsService.send(...)      [5. 短信通知]
        ├─ pushService.send(...)     [推送通知]
        └─ inAppService.send(...)    [站内信通知]

🎯 核心设计原则

Domain 层:定义业务规则和契约(What)

  • "我要发布事件" → IDomainEventPublisher 接口

  • "我要发送通知" → IActivityNotificationPort 接口

Infrastructure 层:提供技术实现(How)

  • "用 Spring Event 发布" → DomainEventPublisherAdapter

  • "用短信/推送/站内信发送" → ActivityNotificationAdapter

这就是依赖倒置原则(DIP)的体现!


🔧 如何扩展通知类型?

非常简单!只需要在 ActivityNotificationAdapter 中添加代码:

@Component

public class ActivityNotificationAdapter {

@Resource private SmsService smsService; // 短信

@Resource private PushService pushService; // 推送

@Resource private InAppService inAppService; // 站内信

@Resource private EmailService emailService; // 邮件 ← NEW!

@Resource private WechatService wechatService; // 微信 ← NEW!

public void notifyActivityCreated(ActivityCreatedEvent event) {

​ // 原有通知

​ smsService.send(...);

​ pushService.send(...);

​ // 新增通知

​ emailService.send(...); // ← 新增邮件通知

​ wechatService.sendTemplateMessage(...); // ← 新增微信通知

}

}

不需要修改 Domain 层任何代码! 这就是 DDD 六边形架构的威力!🚀

Powered by VitePress